
/**
  ******************************************************************************
  * Copyright 2021 The Microbee Authors. All Rights Reserved.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
  * 
  * http://www.apache.org/licenses/LICENSE-2.0
  * 
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  * 
  * @file       srv_hal_mgr.h
  * @author     baiyang
  * @date       2021-12-28
  ******************************************************************************
  */

#pragma once

#ifdef __cplusplus
extern "C"{
#endif

/*----------------------------------include-----------------------------------*/
#include <rthw.h>
#include <rtthread.h>
#include <rtdevice.h>

#include <stdint.h>
#include <stdbool.h>

#include "srv_hal.h"

#include <board_config/board_config.h>
/*-----------------------------------macro------------------------------------*/
#define max_channels 16

/*----------------------------------typedef-----------------------------------*/
/** @ 
  * @brief  
  */
typedef struct {
    enum safety_state _safety_state;
    uint32_t safety_update_ms;
    uint8_t led_counter;
    int8_t safety_button_counter;
    uint8_t safety_press_count; // 0.1s units

    // mask of channels to allow when safety on
    uint16_t safety_mask;

    uint16_t _freq_hz;
    uint16_t _enable_mask;
    bool corked;

    // mask of channels that are running in high speed
    uint16_t fast_channel_mask;
    uint16_t io_fast_channel_mask;
    
    // mask of channels that are 3D capable
    uint16_t _reversible_mask;
    
    // mask of channels that should be reversed at startup
    uint16_t _reversed_mask;
    
    // mask of active ESCs
    uint16_t _active_escs_mask;

    // last sent values are for all channels
    uint16_t last_sent[max_channels];

    // these values are for the local channels. Non-local channels are handled by IOMCU
    uint32_t en_mask;
    uint16_t period[max_channels];
    uint32_t period_ns[max_channels];

    // offset of first local channel
    uint8_t chan_offset;

    // total number of channels on FMU
    uint8_t num_fmu_channels;

    // number of active fmu channels
    uint8_t active_fmu_channels;

    // iomcu output mode (pwm, oneshot or oneshot125)
    enum output_mode iomcu_mode;

    uint16_t _esc_pwm_min;
    uint16_t _esc_pwm_max;

    bool _initialised;
} srv_hal_mgr;

/*----------------------------------variable----------------------------------*/

/*-------------------------------------os-------------------------------------*/

/*----------------------------------function----------------------------------*/
void srv_hal_ctor();

/*
 * Output a single channel, possibly grouped with previous writes if
 * cork() has been called before.
 */
void srv_hal_write(uint8_t chan, uint16_t period_us);

/* Read back current output state, as either single channel or
 * array of channels. On boards that have a separate IO controller,
 * this returns the latest output value that the IO controller has
 * reported */
uint16_t srv_hal_read(uint8_t chan);
void     srv_hal_read2(uint16_t* period_us, uint8_t len);

/*
  set output frequency in HZ for a set of channels given by a mask
 */
void srv_hal_set_freq(uint32_t chmask, uint16_t freq_hz);

/* Output freq (1/period) control */
uint16_t srv_hal_get_freq(uint8_t chan);

void srv_hal_enable_ch(uint8_t chan);
void srv_hal_disable_ch(uint8_t chan);

/*
 set default update rate
*/
void srv_hal_set_default_rate(uint16_t rate_hz);

/*
 * Update channel masks at 1Hz allowing for actions such as dshot commands to be sent
 */
static inline void srv_hal_update_channel_masks() {}

enum safety_state srv_hal_safety_switch_state(void);
bool srv_hal_force_safety_on();
void srv_hal_force_safety_off();
void srv_hal_safety_update(void);

void srv_hal_cork();
void srv_hal_push();
void srv_hal_zero_rc_outputs();

/*
  enable PX4IO SBUS out at the given rate
 */
bool srv_hal_enable_px4io_sbus_out(uint16_t rate_hz);

/*
  setup output mode
 */
void srv_hal_set_output_mode(uint16_t mask, const enum output_mode mode);

/*
  set PWM to send to a set of channels if the FMU firmware dies
*/
void srv_hal_set_failsafe_pwm(uint32_t chmask, uint16_t period_us);

void srv_hal_set_esc_scaling(uint16_t min_pwm, uint16_t max_pwm);

/*------------------------------------test------------------------------------*/

#ifdef __cplusplus
}
#endif



